import random
import math
import os
from genemid_ins_act import *

# path = f'/Users/liuchangkundeimac/real-time-scheduling/file_test/test0/' + 'ann2.log'
# f = open(path,'w')
def lcm(x, y): 
   #  获取最大的数
    if x > y:
        greater = x
    else:
        greater = y
 
    while(True):
        if((greater % x == 0) and (greater % y == 0)):
            lcm = greater
            break
        greater += 1
    return lcm

def Lcm_list(task_set):
    t = 1
    for i in range(len(task_set)):
        t = lcm(t,task_set[i].getPeriod())
    return t
   
def DBF_C(task_set,t,d_set):
    sum = 0
    for i in range(len(task_set)):
        c_i = task_set[i].getComcost()
        p_i = task_set[i].getPeriod()
        D_i = task_set[i].getDDL()
        d_i = d_set[i]
        sum += c_i*(math.floor((t+d_i-D_i)/p_i) + 1)
    return sum
    
def DBF_B(task_set,t,d_set):
    sum = 0
    for i in range(len(task_set)):
        r_i = task_set[i].getUpcost()
        p_i = task_set[i].getPeriod()
        d_i = d_set[i]
        sum += r_i*(math.floor((t-d_i)/p_i) + 1)
    return sum

def cal_reward(t,s1,s2):
    reward = 0
    if(t-s1>=0 and t-s2>=0):
        reward = 1
    else:
        reward = -1
    return reward

# def reward_func(t_list,task_set,d_set):
#     total_reward = 0
#     for i in range(len(t_list)):
#         t = t_list[i]
#         s1 = DBF_C(task_set,t,d_set)
#         s2 = DBF_B(task_set,t,d_set)
#         if(cal_reward(t_list[i],s1,s2) == 1):
#             total_reward += cal_reward(t_list[i],s1,s2)
#         else:
#             total_reward += 0
#     return total_reward

def reward_func(until,task_set,d_set,file_name):
    for i in range(len(task_set)):
        t_i = task_set[i]
        mddl = d_set[i]
        t_i.mid_deadline = mddl
    total_count,up_count,number,AUCT = MidSimuAnnACT(task_set,until,0,file_name)
    return total_count,up_count,number,AUCT

def Ini_dset(task_set):
    dset = []
    for i in range(len(task_set)):
        D_i = task_set[i].getDDL()
        dset.append(D_i)
    return dset

def time_list(t):
    t_list = []
    for i in range(t):
        t_list.append(i+1)
    return t_list

def Channel_uti(task_set):
    u = 0
    for i in range(len(task_set)):
        t_i = task_set[i]
        r_i = t_i.getUpcost()
        p_i = t_i.getPeriod()
        u += r_i/p_i
    return u

def New_dset(task_set):
    dset = []
    for i in range(len(task_set)):
        r_i = task_set[i].getUpcost()
        c_i = task_set[i].getComcost()
        D_i = task_set[i].getDDL()
        d_i = random.randint(r_i,D_i-c_i)
        dset.append(d_i)
    return dset

def GetMaxPeriod(task_set):
    pset = []
    for i in range(len(task_set)):
        p_i = task_set[i].getPeriod()
        pset.append(p_i)
    maxp = 10*max(pset)
    return maxp

def SimuAnnMid1(task_set,file_name):
    path = file_name + 'ann_mid_act.log'
    f = open(path,'a')
    T_init = 100  # 初始最大温度
    alpha = 0.90  # 降温系数
    T_min = 1e-1  # 最小温度，即退出循环条件
    T = T_init
    itr = 10
    U_C = Channel_uti(task_set)
    print("Channel utilization of the task set: ",U_C,file=f)
    d_set = Ini_dset(task_set)
    print("Initial dset:",d_set,file=f)
    # until = Lcm_list(task_set)
    # print("t_max:",until,file=f)
    # if until >= 20000:
    #     until = 20000
    # else:
    #     until = until
    until = GetMaxPeriod(task_set)
    # t_list = time_list(t_max)
    # if(len(t_list) >= 40000):
    #     #t_sample = random.sample(t_list,20000)
    #     t_sample = t_list[:20000]
    #     y = [reward_func(t_sample,task_set,d_set),reward_func(random.sample(t_list[:20000],10000),task_set,d_set)] 
    # else:
    #     t_sample = t_list
    total_count,up_count,number,AUCT = reward_func(until,task_set,d_set,file_name)
    y = [up_count,total_count,100/AUCT]
    print("job number is:",number,file=f)
    while T >= T_min:
        best_d_set = d_set
        y_best = y
        flag = 0
        stop = 0
        for i in range(itr):
            new_d_set = New_dset(task_set)
            print("---------------------------------------------",file=f)
            print("New_dset after check:",new_d_set,file=f)
            # if(len(t_list) >= 40000):
            #     y_new = [reward_func(t_sample,task_set,new_d_set),reward_func(random.sample(t_list[:20000],10000),task_set,d_set)]
            # else:
            #     y_new = [reward_func(t_sample,task_set,new_d_set)]
            new_total_count,new_up_count,new_number,new_AUCT = reward_func(until,task_set,new_d_set,file_name)
            y_new = [new_up_count,new_total_count,100/new_AUCT]
            print("Reward:",y,file=f)
            print("New reward:",y_new,file=f)
            # if y_new > y  or math.exp(-abs(y_new - y) / T > random.random()):
            if y_new > y:
                flag = 1  # 有新值被接受
                print("New value get",file=f)
                d_set = new_d_set
                y = y_new
                if y > y_best:
                    best_d_set = d_set
                    y_best = y
                    print("Best_d_set:",best_d_set,file=f)
            if y_new[0] == number:
                print("It's feasible in upload phase",file=f)
                
        if flag:
            d_set = best_d_set
            y = y_best

        T *= alpha
        
    print("Final result:",d_set,file=f)
    
    return d_set,until